Handling Integrations
Learn how to handle integration requests and follow-up script permissions in the v0 API
Learn how to handle integration requests when a v0 chat pauses and needs input from your app. The short version is:
- Prompt the agent.
- Inspect the latest assistant message and read the chat's
vercelProjectId. - Install the integration with the Vercel API.
- Confirm the install with
POST /v2/chats/{chatId}/messages/resolve. - Handle script permissions if the agent asks for them next.
This guide focuses on the integration flow. For the full task schema, see Resolve Task.
1. Prompt the agent
Start or continue a chat with a request that depends on an integration.
For example:
- "Build a waiting list app with Neon."
- "Create a dashboard that uses Supabase auth."
If the agent can continue without extra setup, it will. If it needs an integration, it will stop and ask your app to handle it.
2. Inspect the latest assistant message
When a chat is blocked on integration setup, inspect the latest assistant message first. Fetch it with:
GET /v2/chats/{chatId}/messages/{messageId}
An integration request surfaces as an agent-action part in the message's parts array with name: "get_or_request_integration". Its data.requestedIntegrations lists the integration names to install (for example, ["Neon"]), and data.requestedMcpPresets lists any MCP presets. You pass these values back in step 4. The message content also describes the request in prose.
Use the latest blocked assistant message only. If you try to resolve an older task after the chat has moved on, resolve-task returns 409 Conflict.
3. Install the integration with the Vercel API
Once you know which integration the assistant is asking for, install or connect it in Vercel.
Use the chat's vercelProjectId for the project-scoped Vercel API calls in this step. In the beta chat response types, vercelProjectId is the linked Vercel project ID. Do not use projectId here. projectId is the separate v0 project ID, and it is deprecated in the chat response.
import { v0 } from 'v0'
const chat = await v0.chats.get({
chatId: '123',
})
if (!chat.vercelProjectId) {
throw new Error('This chat is not linked to a Vercel project yet.')
}
const vercelProjectId = chat.vercelProjectIdThis step happens outside the v0 API. The exact Vercel API calls depend on your integration flow, but these docs are the relevant starting points:
When you call the Vercel endpoint that connects a resource to a project, pass vercelProjectId from the chat.
After the integration is actually connected, return to the v0 chat and confirm it with resolve-task.
4. Confirm the install with resolve-task
Use task.type: "confirmed-steps" after the integration is installed. Pass the integration names exactly as the assistant requested them, such as Neon or Supabase.
import { v0 } from 'v0'
await v0.messages.resolve({
chatId: '123',
task: {
type: 'confirmed-steps',
connectedIntegrationNames: ['Neon'],
},
})If you are rejecting the integration request instead of approving it, pass an empty array:
{
"task": {
"type": "confirmed-steps",
"connectedIntegrationNames": []
}
}You can also confirm other setup work with the same task type, including MCP presets, scripts, and environment variables.
5. Handle script permissions if needed
After the integration is connected, the assistant may ask for permission to run follow-up scripts, such as database setup or migrations.
When that happens, inspect the latest assistant message again. The pending action surfaces as a tool-call part in the message's parts array. While the agent is waiting for your approval, that part includes a suggestedPermissions array.
To approve the request, call resolve with task.type: "confirmed-permissions" and pass the suggestedPermissions objects back unchanged as task.permissions.
The submitted permissions must match the ones currently pending on the latest blocked assistant message, or resolve returns 409 Conflict.
{
"task": {
"type": "confirmed-permissions",
"permissions": [
{
"type": "ALLOW_DYNAMIC_TOOL_STRICT",
"toolName": "SystemAction",
"input": {
"systemAction": "executeScript",
"executeScript": "/scripts/setup-db.sql"
}
}
]
}
}To reject the request, ignore the permission request and send any other follow-up message.
Example Flow
Here is the full flow in plain English:
- Your app prompts v0 to build something that needs Neon.
- The assistant stops and asks for the Neon integration, surfaced as a
get_or_request_integrationagent-action part. - Your backend reads
vercelProjectIdfromGET /v2/chats/{chatId}and uses that value in the Vercel API calls that connect Neon. - Your backend calls
POST /v2/chats/{chatId}/messages/resolvewithconnectedIntegrationNames: ["Neon"]. - The assistant resumes. If it needs to run a migration script, it stops again with a
tool-callpart that carriessuggestedPermissions. - Your backend passes those
suggestedPermissionsback in aconfirmed-permissionstask to approve.
That is the complete pattern for handling integrations in the Platform API.